<template>
  <div class="permissionRoles">
    <el-tabs>
      <el-tab-pane
        v-for="(item, key) in treeData"
        :key="key"
        :value="item.id"
        :label="item.label"
      >
        <div class="common-box">
          <vxe-table
            ref="commonTable"
            border
            :height="height"
            :data="item.children"
            :loading="loading"
            :resizable="true"
          >
            <vxe-column
              :title="$t('模块')"
              width="200px"
              align="right"
              header-align="right"
            >
              <template #header>
                <span class="label" @click="handleClickAllLabel(item)">{{
                  $t("模块")
                }}</span
                ><vxe-checkbox
                  v-model="item.checked"
                  @change="changeBox($event, item)"
                />
              </template>
              <template #default="{ row }">
                <span class="label" @click="handleClickLabel(row)">{{
                  row.label
                }}</span
                ><vxe-checkbox
                  v-model="row.checked"
                  @change="changeBox($event, row)"
                />
              </template>
            </vxe-column>
            <vxe-column :title="$t('菜单/按钮')" min-width="700">
              <template #default="{ row }">
                <div
                  v-for="i in row.children"
                  :key="i.id"
                  class="box-column-label"
                  :class="{ noChild: !i.children }"
                >
                  <div class="box-column-menu">
                    <vxe-checkbox
                      v-model="i.checked"
                      :content="i.label"
                      @change="changeBox($event, i)"
                    />
                  </div>
                  <div v-if="i.children" class="box-column-btn">
                    <div
                      v-for="o in i.children"
                      :key="o.id"
                      class="box-column-label"
                      :class="{ noChild: !o.children }"
                    >
                      <div class="box-column-menu">
                        <vxe-checkbox
                          v-model="o.checked"
                          :content="o.label"
                          @change="
                            changeBox($event, o, [i.id, row.id, item.id])
                          "
                        />
                      </div>
                      <div v-if="o.children" class="box-column-btn">
                        <vxe-checkbox
                          v-for="btn in o.children"
                          :key="btn.id"
                          v-model="btn.checked"
                          :content="btn.label"
                          style="margin: 5px 10px"
                          @change="changeBox($event, btn)"
                        />
                      </div>
                    </div>
                  </div>
                </div>
              </template>
            </vxe-column>
          </vxe-table>
        </div>
      </el-tab-pane>
    </el-tabs>
    <div class="box_card_footer">
      <el-button @click="handleCancel" class="cancel-btn">{{
        $t("返回")
      }}</el-button>
      <el-button
        :loading="saveLoading"
        @click="handleSubmit"
        class="save-btn"
        >{{ $t("保存") }}</el-button
      >
    </div>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted, watch } from "vue";
import * as api from "@/api/index";
import { setTableHeight, debounce } from "@/utils/mUtils";
const props = defineProps({
  params: {
    type: Object,
    default: () => {
      return {};
    },
  },
});

const checkedKeys = ref([]);
const treeData = ref([]);
const height = ref(400);
const loading = ref(false);
const ids = ref([]);
const saveLoading = ref(false);

async function getRolesTree() {
  loading.value = false;
  try {
    const { data } = await api.default.system.role.getTree(props.params);
    adjustTableHeight();
    checkedKeys.value = data.checkedKeys;
    treeData.value = data.menus;
    setMenusSelected(treeData.value);
    for (let i = 0; i < 3; i++) {
      checkedParentBox(treeData.value);
    }
    loading.value = false;
  } catch {
    loading.value = false;
  }
}
getRolesTree();
function setMenusSelected(data) {
  if (!checkedKeys.value) return;
  data.forEach((item) => {
    if (checkedKeys.value.includes(Number(item.id))) {
      item.checked = true;
    }
    if (item.children) {
      setMenusSelected(item.children);
    }
  });
}
function checkedParentBox(data, id) {
  data.forEach((item) => {
    if (id) {
      if (id.includes(item.id)) {
        item.checked = true;
      }
    }
    if (item.children) {
      if (!id) {
        const checkedChild = item.children.filter((i) => i.checked);
        if (checkedChild.length === 0) {
          item.checked = false;
        } else {
          item.checked = true;
        }
      }
      checkedParentBox(item.children, id);
    }
  });
}
function adjustTableHeight() {
  nextTick(async () => {
    height.value = setTableHeight();
  });
}
async function handleSubmit() {
  const params = {
    menuIds: getSelectedId(treeData.value),
    roleId: props.params.roleId,
  };
  saveLoading.value = true;
  try {
    await api.default.system.role.addEditRole(params, true);
    ElMessage.success("操作成功");
    handleCancel();
    saveLoading.value = false;
  } finally {
    saveLoading.value = false;
  }
}
function handleCancel() {
  emit("roleFuncSubmit");
}
function changeBox({ value }, row, id) {
  if (row.children) {
    row.children.forEach((item) => {
      item.checked = value;
      changeBox({ value }, item);
    });
  }
  checkedParentBox(treeData.value, id);
}
function getSelectedId(data) {
  data.forEach((item) => {
    if (item.checked) {
      ids.value.push(item.id);
    }
    if (item.children) {
      getSelectedId(item.children);
    }
  });
  return ids.value;
}
function handleClickLabel(row) {
  row.checked = !row.checked;
  changeBox({ value: row.checked }, row);
}
function handleClickAllLabel(item) {
  item.checked = !item.checked;
  if (item.children && item.children.length > 0) {
    item.children.forEach((it) => {
      it.checked = item.checked;
      changeBox({ value: item.checked }, it);
    });
  }
}
const emit = defineEmits(["roleFuncSubmit"]);
onMounted(() => {
  window.onresize = debounce(adjustTableHeight, 100);
});
</script>
<style lang="scss" scoped>
:deep() {
  .el-tabs__header {
    padding: 0 10px !important;
  }

  .vxe-header--column {
    padding: 6px 0 !important;
    color: #333;
    background-color: #eff3f8 !important;
  }

  .vxe-body--column {
    padding: 6px 0 !important;
  }

  .vxe-checkbox--label {
    color: #606266 !important;
  }
}

.box-column-label {
  position: relative;
  padding: 5px 0 10px;
  border-bottom: 1px solid #e8eaec;

  &::before {
    position: absolute;
    top: -1px;
    display: block;
    width: 100%;
    height: 1px;
    content: "";
    background-color: #e8eaec;
  }

  > div {
    display: inline-block;
    vertical-align: middle;
  }

  .box-column-menu {
    width: 15%;
  }

  .box-column-btn {
    width: 80%;
    padding-left: 3%;
    border-left: 1px solid #e8eaec;
  }

  &:last-child {
    border: 0;
  }

  &:first-child {
    &::before {
      height: 0;
    }
  }

  &.noChild {
    display: inline-block;
    margin-right: 20px;
    vertical-align: middle;
    border: 0;

    .box-column-menu {
      width: auto;
      border: 0;
    }

    &::before {
      height: 0;
    }
  }
}

.permissionRoles {
  position: absolute;
  top: 0;
  z-index: 99;
  width: 100%;
  height: 100%;
  background-color: #fff;
}

.box_card_footer {
  width: 100%;
  height: 50px;
  padding: 10px 0;
  text-align: center;
  background-color: #fff;
  position: absolute;
}

.label {
  margin-right: 10px;
  color: #606266 !important;
  vertical-align: middle;
  cursor: pointer;
}
</style>
